package com.finance.report.service;


import com.finance.base.constant.BaseConstants;
import com.finance.base.exception.BaseException;
import com.finance.framework.lang.Page;
import com.finance.framework.lang.PageResultBO;
import com.finance.report.bean.pojo.LogisticsDataView;
import com.finance.report.bean.pojo.ManSalary;
import com.finance.report.bean.pojo.ManSalaryDetail;
import com.finance.report.dao.ManSalaryMapper;
import com.finance.util.DateUtil;
import com.mysql.jdbc.MysqlErrorNumbers;
import net.sf.json.JSONObject;
import org.apache.commons.collections.CollectionUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.BadSqlGrammarException;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Isolation;
import org.springframework.transaction.annotation.Transactional;

import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.Random;


@Service
public class ManSalaryService implements IManSalaryService {
    private Logger logger = LoggerFactory.getLogger(this.getClass());

    @Autowired
    private ManSalaryMapper manSalaryMapper;

    @Override
    public PageResultBO<ManSalary> listByPage(Page page) {
        PageResultBO<ManSalary> pageResultBO = new PageResultBO<ManSalary>();
        List<ManSalary> list = manSalaryMapper.listByPage(page);
        pageResultBO.setTotalRecord(page.getTotalRecord());
        pageResultBO.setPageSize(page.getPageSize());
        pageResultBO.setPageNo(page.getPageNo());
        pageResultBO.setDataList(list);
        return pageResultBO;
    }

    @Override
    public PageResultBO<Map<String,Object>> listSalaryByPage(Page page){
        PageResultBO<Map<String,Object>> pageResultBO = new PageResultBO<Map<String,Object>>();
        List<Map<String,Object>> list = manSalaryMapper.listSalaryByPage(page);
        pageResultBO.setTotalRecord(page.getTotalRecord());
        pageResultBO.setPageSize(page.getPageSize());
        pageResultBO.setPageNo(page.getPageNo());
        pageResultBO.setDataList(list);
        return pageResultBO;
    }

    @Override
    public PageResultBO<LogisticsDataView> getOrdersDetails(Page page) {
        PageResultBO<LogisticsDataView> pageResultBO = new PageResultBO<LogisticsDataView>();
        List<LogisticsDataView> list = null;
        try {
            list = manSalaryMapper.getOrdersDetails(page);
        }catch (BadSqlGrammarException e){
            int errCode = e.getSQLException().getErrorCode();
            if(errCode == MysqlErrorNumbers.ER_NO_SUCH_TABLE){
                throw new BaseException(BaseConstants.ERR_TABLE_NAME_NOT_EXIST);
            }
        }
        pageResultBO.setTotalRecord(page.getTotalRecord());
        pageResultBO.setPageSize(page.getPageSize());
        pageResultBO.setPageNo(page.getPageNo());
        pageResultBO.setDataList(list);
        return pageResultBO;
    }

    @Override
    public ManSalary getByUserCode(String userCode, String month) {
        return manSalaryMapper.getByUserCode(userCode,month);
    }

    @Override
    public ManSalary getByUserCodeForLock(String userCode, String month) {
        return manSalaryMapper.getByUserCodeForLock(userCode,month);
    }

    @Override
    public List<ManSalaryDetail> getSalaryDetails(String userCode, String salaryMonth) {
        return manSalaryMapper.getSalaryDetails(userCode, salaryMonth);
    }

    @Override
    @Transactional(rollbackFor = Exception.class,isolation = Isolation.READ_COMMITTED)
    public void addManSalaryWithDetail(ManSalary manSalary) throws Exception {
        try{
            this.manSalaryMapper.addManSalary(manSalary);
            this.logger.info("插入月报表数据:{} ",String.valueOf(manSalary));
            this.logger.info("插入时间：{}",new Date().toString());
                 List<ManSalaryDetail> list = manSalary.getManSalaryDetailList();
                if(list != null && list.size() > 0){
                    this.logger.info("新增withDetail配送员月报表明细list：{} 配送员：{}", list.toString(), manSalary.getUserCode());
                }
                List<ManSalaryDetail> details = this.manSalaryMapper.getSalaryDetails(manSalary.getUserCode(),manSalary.getSalaryMonth());
                if(CollectionUtils.isNotEmpty(list)){
                    for(ManSalaryDetail detail : list){
                        if(!details.contains(detail)){
                            this.logger.info("新增withDetail 供应商：{}", detail.getSupplierCode());
                            this.manSalaryMapper.addManSalaryDetail(detail);
                        }
                    }
                }
         }catch (Exception e){
            this.logger.error("异常原因：{} 锁{}",String.valueOf(e),String.valueOf(manSalary.getSalaryMonth() + manSalary.getUserCode()));
            throw new Exception(e.getMessage());
        }
             this.logger.info("新增月报表withDetail成功锁{}",String.valueOf(manSalary.getSalaryMonth() + manSalary.getUserCode()));
    }

    @Override
    @Transactional(rollbackFor = Exception.class,isolation = Isolation.READ_COMMITTED)
    public void addManSalaryDetail(ManSalaryDetail manSalaryDetail) {
        this.manSalaryMapper.addManSalaryDetail(manSalaryDetail);
        this.logger.info("新增配送员月报表明细：{}", manSalaryDetail.toString());
     }

    /**
     *  for test
     * @param manSalary
     * @throws Exception
     */
    @Override
    @Transactional(rollbackFor = Exception.class,isolation = Isolation.READ_COMMITTED)
    public void updateManSalary(ManSalary manSalary) throws Exception {
        String tag = DateUtil.dateFormat(new Date(),"yyyyMMddHHmmssSSS");
        logger.info("此处标记：{}", tag);
        logger.info("{}即将更新数据 user: {} month:{}", new String[]{tag,manSalary.getUserCode(),manSalary.getSalaryMonth()});
        ManSalary oldMansalary = this.manSalaryMapper.getByUserCode(manSalary.getUserCode(),manSalary.getSalaryMonth());
        logger.info("{}更新前先打印DB中数据：{}", tag, JSONObject.fromObject(oldMansalary));
        logger.info("{}要更新的D数据：{}", tag, JSONObject.fromObject(oldMansalary));
        logger.info("{}条件user:{},条件month:{},条件version:{}", new String[]{tag,oldMansalary.getUserCode(), oldMansalary.getSalaryMonth(), oldMansalary.getVersion() + ""});
        logger.info("{}新数据user:{},条件month:{},条件version:{}", new String[]{tag,manSalary.getUserCode(), manSalary.getSalaryMonth(), manSalary.getVersion() + ""});
        this.logger.info("待更新月报表{}",String.valueOf(manSalary));
        boolean result = this.manSalaryMapper.updateManSalary(manSalary) == 1;
        if(!result){
            this.logger.info("manSalary更新 失败分析 旧supplierFee：{} 旧totalFee：{} 新supplierFee：{} 新totalFee：{} 版本号比对：{}",new String[]{String.valueOf(oldMansalary.getSupplierFee()),String.valueOf(oldMansalary.getTotalFee()),String.valueOf(manSalary.getSupplierFee()),String.valueOf(manSalary.getTotalFee()),String.valueOf(oldMansalary.getVersion() == manSalary.getVersion())});
            this.logger.error("{}更新薪资失败{}", tag, manSalary.getUserCode());
            throw new Exception(tag + "更新薪资失败 user:" + manSalary.getUserCode());
        }else{
            this.logger.info("{}更新薪资成功{}月份{}",new String[]{tag, manSalary.getUserCode(), manSalary.getSalaryMonth()});
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class,isolation = Isolation.READ_COMMITTED)
    public void updateManSalary(ManSalary manSalary, String wayBillNum) throws Exception {
        String tag = DateUtil.dateFormat(new Date(),"yyyyMMddHHmmssSSS");
        logger.info("此处标记：{},单号", tag, wayBillNum);
        logger.info("{}即将更新数据 user: {} month:{},单号：{}", new String[]{tag, manSalary.getUserCode(), manSalary.getSalaryMonth(), wayBillNum});
        ManSalary oldMansalary = this.manSalaryMapper.getByUserCode(manSalary.getUserCode(), manSalary.getSalaryMonth());
        logger.info("{}更新前先打印DB中数据：{},单号：{}", new String[]{tag, JSONObject.fromObject(oldMansalary).toString(), wayBillNum});
        logger.info("{}要更新的D数据：{},单号：{}", new String[]{tag, JSONObject.fromObject(oldMansalary).toString(), wayBillNum});
        logger.info("{}条件user:{},条件month:{},条件version:{},单号：{}", new String[]{tag, oldMansalary.getUserCode(), oldMansalary.getSalaryMonth(), oldMansalary.getVersion()+"", wayBillNum});
        logger.info("{}新数据user:{},条件month:{},条件version:{},单号：{}", new String[]{tag, manSalary.getUserCode(), manSalary.getSalaryMonth(), manSalary.getVersion()+"", wayBillNum});
        logger.info("待更新的快递员薪资月报数据：{} 时间：{} 运单号：{} version：{}",new String[]{String.valueOf(manSalary), new Date().toString(), wayBillNum, String.valueOf(manSalary.getVersion())});
        boolean result = false;
        if(oldMansalary != null && manSalary != null && oldMansalary.getVersion() == manSalary.getVersion()){
            int count = this.manSalaryMapper.updateManSalary(manSalary);
            result = count == 1;
            this.logger.info("月报表数据更新条数：{} 运单：{} 时间：{}",new String[]{String.valueOf(count),wayBillNum,new Date().toString()});
        }
        if(!result){
            this.logger.error("{}更新薪资失败{} 单号{}", new String[]{tag, manSalary.getUserCode(), wayBillNum});
            this.logger.info("失败分析 旧supplierFee：{} 旧totalFee：{} 新supplierFee：{} 新totalFee：{} 版本号比对：{} 运单号：{}",new String[]{String.valueOf(oldMansalary.getSupplierFee()),String.valueOf(oldMansalary.getTotalFee()),String.valueOf(manSalary.getSupplierFee()),String.valueOf(manSalary.getTotalFee()),String.valueOf(oldMansalary.getVersion() == manSalary.getVersion()),wayBillNum});
            throw new Exception(tag + "更新薪资失败 user:" + manSalary.getUserCode());
        }else{
            this.logger.info("{}更新薪资成功{}月份{} 单号{}", new String[]{tag, manSalary.getUserCode(), manSalary.getSalaryMonth(), wayBillNum});
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class,isolation = Isolation.READ_COMMITTED)
    public boolean updateManSalaryDetail(ManSalaryDetail manSalaryDetail) {
        int result = this.manSalaryMapper.updateSalaryDetail(manSalaryDetail);
        this.logger.info("更新商家{}在{}月明细成功{}条", new String[]{manSalaryDetail.getSupplierCode(), manSalaryDetail.getSalaryMonth(), result + ""});
        return result == 1;
    }

    @Override
    @Transactional(rollbackFor = Exception.class,isolation = Isolation.READ_COMMITTED)
    public boolean updateManSalaryDetail(ManSalaryDetail manSalaryDetail,String wayBillNum) {
        int result = this.manSalaryMapper.updateSalaryDetail(manSalaryDetail);
        this.logger.info("更新商家{}在{}月明细成功{}条,单号：{}", new String[]{manSalaryDetail.getSupplierCode(), manSalaryDetail.getSalaryMonth(), result + "", wayBillNum});
        return result == 1;
    }

    @Override
    public ManSalaryDetail getDetailBySupplierCode(ManSalary manSalary, String supplierCode) {
        return this.manSalaryMapper.getBySupplierCode(manSalary.getUserCode(), manSalary.getSalaryMonth(), supplierCode);
    }

    @Override
    public ManSalary getByUserCodeRandom(String userCode, String month) {
        return manSalaryMapper.getByUserCodeRandom(userCode,month,new Random().nextInt(50000));
    }

}
